import java.awt.Color;
import java.util.*;
import java.io.*;
import java.lang.reflect.*;

public class ConradSab implements IPlayer{ 
  // Snooping where we don't belong
  private Field _fplayers, _fmatrix, _fhypo, _fmoves, _fgbColor;
  private Object[] _players = new Object[2];
  private Object _us, _them;

  protected Color _color, _hisColor = null;
  protected IBoard _board;

  // Our worker thread that scouts for bestMove
  protected CScoutThreadSab _scThr;
  // Tourney-limited gameclock (hundredths of seconds)
  protected final int _maxCSeconds = 95;
  // This needs to be public so child/worker thread can set it
  public Integer bestMove;

  public void beginTurn(){
    // Setup accessors to hidden data

    if (_players[0] == null){
      try {
        _players = ((ArrayList)_fplayers.get(_board)).toArray();
      }
      catch (Exception e){}
      _us = this;
      if (_players[0] == _us) _them = _players[1];
      else _them = _players[0];
      System.out.println("Suck a fat one " + _them.getClass().
          getName() + ", you're going down!");
    }

    // find the opponent's colour if we havn't before (this should only
    // happen once in a tourney and we have no better places to trigger
    // for it -- joinBoard() might be called before the other player
    // has joined the board, and constructor is almost useless)

    if (_hisColor == null){
      Iterator pInfoItr = _board.getPlayers();
      _hisColor = ((IPlayerInfo)pInfoItr.next()).getColor();
      if(_hisColor == _color) _hisColor = ((IPlayerInfo)pInfoItr.next()).getColor();

      // let's change the gameboard colour at the same time!

      try {
      _fgbColor.set(_board, new Color(0x90, 0x10, 0x10));
      }
      catch (Exception e){}
    }

    bestMove = null;

    // Pass ourself to the scout thread; the scout thread will search
    // iteratively deeper, setting this.bestMove every time. We let it run
    // for as long as _maxSeconds, then destroy it.
    _scThr = new CScoutThreadSab(this, _board, _color, _hisColor);
    _scThr.start();
    try{
      _scThr.join(10 * _maxCSeconds);
    }
    catch (InterruptedException ie){
    }
    finally{
      if (bestMove == null)
        System.out.println("Fuck, we don't have a move.");
    }
    _scThr.stop();
    _scThr = null;

    if (bestMove == 64)
      _board.pass(this);
    else
      if (!_board.placePiece(this, bestMove >> 3, bestMove & 7))
        _board.pass(this);
  }

  public void joinBoard(IBoard board, Color color){
    _board = board;
    _color = color;

    Class gameboard = GameBoard.class;
    try{
      _fplayers = gameboard.getDeclaredField("_players");
      _fmatrix  = gameboard.getDeclaredField("_matrix");
      _fhypo    = gameboard.getDeclaredField("_hypothetical");
      _fmoves   = gameboard.getDeclaredField("_moves");
      _fgbColor = gameboard.getDeclaredField("_boardColor");

      _fplayers.setAccessible(true);
      _fmatrix. setAccessible(true);
      _fhypo.   setAccessible(true);
      _fmoves.  setAccessible(true);
      _fgbColor.setAccessible(true);
    }
    catch(Exception e){
      e.printStackTrace();
    }
  }

  public      ConradSab(){                     }
  public void   endTurn(){                     }
  public Color getColor(){ return _color;      }
  public String getName(){ return "ConradSab"; }
} 
